package com.gin.kotlin.gf2gamecommunity.routes

import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import androidx.navigation.toRoute
import androidx.paging.compose.collectAsLazyPagingItems
import com.gin.kotlin.enums.CommentSort
import com.gin.kotlin.form.CommentListForm
import com.gin.kotlin.gf2gamecommunity.R
import com.gin.kotlin.gf2gamecommunity.app.App
import com.gin.kotlin.gf2gamecommunity.base.composable.ConfirmDialog
import com.gin.kotlin.gf2gamecommunity.composable.ComplaintDialog
import com.gin.kotlin.gf2gamecommunity.composable.HtmlText
import com.gin.kotlin.gf2gamecommunity.composable.MessageIconButton
import com.gin.kotlin.gf2gamecommunity.composable.OpenLinkButton
import com.gin.kotlin.gf2gamecommunity.composable.ReplyFAB
import com.gin.kotlin.gf2gamecommunity.composable.UserAvatar
import com.gin.kotlin.gf2gamecommunity.navi.GF2Navigator
import com.gin.kotlin.gf2gamecommunity.viewmodel.CommentListViewModel
import com.gin.kotlin.gf2gamecommunity.viewmodel.MessageViewModel
import com.gin.kotlin.gf2gamecommunity.viewmodel.TopicListViewModel
import com.gin.kotlin.gf2gamecommunity.viewmodel.UserViewModel
import com.gin.kotlin.response.comment.CommentInfo
import com.gin.kotlin.response.user.UserInfo
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable


/**
 * 扩展方法
 * @receiver [NavGraphBuilder]
 */
fun NavGraphBuilder.commentList(navigator: GF2Navigator, messageViewModel: MessageViewModel) = composable<CommentListRoute>(
    // 从屏幕右侧进入，持续500毫秒
    enterTransition = { slideInHorizontally(tween(500)) { it } },
    // 从屏幕右侧退出，持续500毫秒
    exitTransition = { slideOutHorizontally(tween(500)) { it } },
) {
    CommentListComposable(navigator = navigator, route = it.toRoute(), messageViewModel = messageViewModel)
}


/**
 * 主题详情（回复列表）路线
 * @param topicId 主题ID
 * @param sort 排序方式
 * @param onlyAuthor 只看楼主
 * @constructor
 */
@Serializable
data class CommentListRoute(
    val topicId: Int,
    val sort: CommentSort = CommentSort.NORMAL,
    val onlyAuthor: Boolean = false,
    val temporaryTitle: String? = null,
) {
    fun toForm() = CommentListForm(
        topicId = topicId,
        sort = sort,
        onlyAuthor = onlyAuthor,
    )
}

/**
 * 主题详情（回复列表）组件
 * @param route CommentListRoute
 * @param onPopBackStack () -> Unit
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CommentListComposable(
    route: CommentListRoute,
    navigator: GF2Navigator,
    messageViewModel: MessageViewModel = viewModel(),
    commentListViewModel: CommentListViewModel = viewModel(),
    topicListViewModel: TopicListViewModel = viewModel()
) {
    navigator.apply {
        var expanded by remember { mutableStateOf(false) }
        var expandedSort by remember { mutableStateOf(false) }
        val coroutineScope = rememberCoroutineScope()

        var form by remember { mutableStateOf(route.toForm()) }


        // paging加载主题列表
        val lazyPagingItems = commentListViewModel.commentList.fetch(form).collectAsLazyPagingItems()
        // 如果发帖flag为true，说明刚刚成功发布了回复需要更新当前数据
        if (App.INSTANCE.replyFlag) {
            App.INSTANCE.replyFlag = false
            LaunchedEffect(Unit) {
                delay(500)
                lazyPagingItems.refresh()
            }
        }
        val lazyListState = rememberLazyListState()

        var showDeleteDialog by remember { mutableStateOf(false) }
        var commentIdToDelete by remember { mutableIntStateOf(0) }

        var showComplaintDialog by remember { mutableStateOf(false) }
        var complaintTarget = CommentInfo()

        //  主楼详情
        val topicDetailState = topicListViewModel.topicDetail.fetch(route.topicId).observeAsState()
        val topicDetail = topicDetailState.value?.data
        val isFavor = topicDetail?.isFavor


        Scaffold(
            topBar = {
                TopAppBar(navigationIcon = {
                    IconButton(onClick = { onPopBackStack() }) {
                        Icon(imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "后退")
                    }
                }, actions = {
                    MessageIconButton({ onNavigateToMessageList(it) }, messageViewModel)
                    Box {
                        IconButton(onClick = { expanded = !expanded }) {
                            Icon(Icons.Filled.Menu, contentDescription = "菜单")
                        }
                        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
                            DropdownMenuItem(text = { Text("刷新") }, leadingIcon = {
                                Icon(imageVector = Icons.Filled.Refresh, contentDescription = "刷新")
                            }, onClick = {
                                lazyPagingItems.refresh()
                                coroutineScope.launch { lazyListState.scrollToItem(0, 0) }
                                expanded = false
                            })
                            DropdownMenuItem(text = { Text("分享") }, leadingIcon = {
                                Icon(imageVector = Icons.Filled.Share, contentDescription = "分享")
                            }, onClick = {
                                topicListViewModel.share(route.topicId)
                                expanded = false
                            })
                            DropdownMenuItem(text = { Text("搜索") }, leadingIcon = {
                                Icon(imageVector = Icons.Filled.Search, contentDescription = "搜索")
                            }, onClick = {
                                onNavigateToSearch(SearchRoute())
                                expanded = false
                            })
                            DropdownMenuItem(text = { Text("回复排序") }, leadingIcon = {
                                Icon(painterResource(R.drawable.ic_sort_24), contentDescription = "回复排序")
                            }, onClick = {
                                expandedSort = true
                                expanded = false
                            })
                            if (!route.onlyAuthor) DropdownMenuItem(text = { Text("只看楼主") }, leadingIcon = {
                                Icon(imageVector = Icons.Filled.Person, contentDescription = "只看楼主")
                            }, onClick = {
                                onNavigateToCommentList(route.copy(onlyAuthor = true))
                            })
                            OpenLinkButton(navigator, true)

                            if (isFavor != null) {
                                DropdownMenuItem(text = { Text(if (isFavor) "已收藏" else "收藏") }, leadingIcon = {
                                    Icon(painterResource(if (isFavor) R.drawable.ic_star_24 else R.drawable.ic_star_outline_24), contentDescription = "收藏按钮")
                                }, onClick = {
                                    topicListViewModel.favor(route.topicId)
                                })
                            }
                        }

                        DropdownMenu(expanded = expandedSort, onDismissRequest = { expandedSort = false }) {
                            CommentSort.entries.forEach {
                                DropdownMenuItem(text = { Text(it.des) }, leadingIcon = {
                                    if (form.sort == it) Icon(Icons.Filled.Check, contentDescription = null)
                                }, onClick = {
                                    form = form.copy(sort = it)
                                    expandedSort = false
                                })
                            }
                        }
                    }
                }, title = {
                    Text(text = listOf(
                        route.temporaryTitle,
                        topicDetail?.title,
                    ).firstNotNullOfOrNull { it } ?: "主题标题", maxLines = 2)
                })
            },
            floatingActionButton = {
                ReplyFAB(ReplyRoute(route.topicId), onNavigateToReply = { onNavigateToReply(it) }, onRefresh = { lazyPagingItems.refresh() })
            }
        )
        { paddingValues ->
            val modifier = Modifier.padding(paddingValues)
            if (lazyPagingItems.itemCount == 0) {
                Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                    CircularProgressIndicator()
                }
            } else {
                Box(modifier) {
                    LazyColumn(verticalArrangement = Arrangement.spacedBy(2.dp), contentPadding = PaddingValues(4.dp), state = lazyListState) {
                        items(lazyPagingItems.itemCount) { index ->
                            CommentItem(item = lazyPagingItems[index]!!,
                                topicId = route.topicId,
                                topicTitle = route.temporaryTitle,
                                index = index,
                                onNavigateToUserCenter = { onNavigateToUserCenter(it) },
                                onNavigateToCommentSingle = { onNavigateToCommentSingle(it) },
                                onConfirmDeleteComment = { commentId ->
                                    showDeleteDialog = true
                                    commentIdToDelete = commentId
                                },
                                onComplaint = { info ->
                                    complaintTarget = info
                                    showComplaintDialog = true
                                },
                                onNavigateToReply = { onNavigateToReply(ReplyRoute(route.topicId, it)) },
                                onClickImage = { item, url -> onNavigateToImagePreView(ImagePreViewRoute(url, item.picList ?: listOf(url))) })
                        }
                    }
                }
            }
        }

        if (showDeleteDialog) ConfirmDialog(
            onDismissRequest = { showDeleteDialog = false },
            onConfirmation = {
                commentListViewModel.remove(topicId = route.topicId, commentId = commentIdToDelete) {
                    showDeleteDialog = false
                    lazyPagingItems.refresh()
                }
            }
        ) { Text("确认删除该回复?") }

        if (showComplaintDialog) ComplaintDialog(route.topicId, complaintTarget, onDismissRequest = { showComplaintDialog = false })
    }
}

@Composable
fun CommentItem(
    item: CommentInfo,
    topicId: Int,
    onConfirmDeleteComment: (commentId: Int) -> Unit,
    index: Int = 0,
    topicTitle: String? = null,
    showCommentReply: Boolean = true,
    commentListViewModel: CommentListViewModel = viewModel(),
    topicListViewModel: TopicListViewModel = viewModel(),
    userViewModel: UserViewModel = viewModel(),
    onComplaint: (CommentInfo) -> Unit,
    onClickImage: (item: CommentInfo, url: String) -> Unit,
    onNavigateToCommentSingle: (CommentSingleRoute) -> Unit = { _ -> },
    onNavigateToUserCenter: (UserCenterRoute) -> Unit,
    onNavigateToReply: (Int) -> Unit,
) {
    // 用户名+等级
    val username = remember(item.userId) { derivedStateOf { "${item.userNickName} lv.${item.userLevel} ${item.ipLocation}" } }
    // 楼层 发布时间
    val floor = remember(item) { derivedStateOf { "[${item.floorNum}L] ${item.createTime}" } }

    val likeCount = remember(item.commentId) { mutableIntStateOf(item.likeNum) }

    userViewModel.cUser.fetch()
    val userInfoState = userViewModel.cUser.liveData.observeAsState()

    Card(
        modifier = Modifier.fillMaxWidth(),
        border = BorderStroke(2.dp, CardDefaults.cardColors().disabledContentColor),
    ) {
        Row(modifier = Modifier.padding(4.dp)) {
            //  头像
            Column {
                UserAvatar(item.userAvatar, Modifier
                    .clip(CircleShape)
                    .size(48.dp)
                    .clickable { onNavigateToUserCenter(UserCenterRoute(item.userId)) })
            }
            Column {
                Column(modifier = Modifier
                    .fillMaxWidth()
                    .clickable { onNavigateToUserCenter(UserCenterRoute(item.userId)) }) {
                    // 用户名 等级 属地
                    Text(username.value)
                    // 楼层 发布时间
                    Text(floor.value, modifier = Modifier.graphicsLayer { alpha = 0.7f })
                    // 分割线
                    HorizontalDivider(Modifier.height(2.dp))
                }
                // 正文
                HtmlText(item = item, html = item.content, onClickImage = onClickImage)

                //  楼中楼
                if (showCommentReply) {
                    item.commentReply?.also { commentReply ->
                        Column(verticalArrangement = Arrangement.spacedBy(2.dp),
                            modifier = Modifier
                                .padding(PaddingValues(start = 20.dp, end = 20.dp, top = 8.dp))
                                .fillMaxWidth()
                                .clickable {
                                    onNavigateToCommentSingle(CommentSingleRoute(topicId = topicId, commentId = item.commentId, topicTitle = topicTitle ?: "楼中楼"))
                                }) {
                            commentReply.take(2).forEachIndexed { index, subInfo ->
                                SubCommentItem(subInfo,
                                    index = index,
                                    userInfoState = userInfoState,
                                    onClickImage = onClickImage,
                                    onNavigateToUserCenter = onNavigateToUserCenter,
                                    onConfirmDeleteComment = { onConfirmDeleteComment(it) },
                                    modifier = Modifier.fillMaxWidth(),
                                    showButtons = false)
                            }
                            if (commentReply.size > 2) {
                                Text("点击查看全部 ${commentReply.size} 个回复")
                            }
                        }
                    }
                }

                // 底部操作按钮
                Row(horizontalArrangement = Arrangement.End, modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
                    if (userInfoState.value?.uid == item.userId) IconButton(onClick = { onConfirmDeleteComment(item.commentId) }) {
                        Icon(Icons.Filled.Delete, contentDescription = "删除回复")
                    }
                    // 举报
                    IconButton(onClick = { onComplaint(item) }) {
                        Icon(painterResource(R.drawable.ic_report_problem_24), contentDescription = "举报")
                    }
                    if (item.commentId > 0) IconButton(onClick = {
                        onNavigateToReply(item.commentId)
                    }) {
                        Icon(painterResource(R.drawable.ic_comment_24), contentDescription = "楼中楼")
                    }
                    // 赞
                    IconButton(onClick = {
                        val onSuccess = {
                            likeCount.value += if (item.isLike) -1 else 1
                            item.isLike = !item.isLike
                            item.isDislike = false
                        }
                        if (item.commentId == 0) topicListViewModel.like(topicId, onSuccess)
                        else commentListViewModel.like(topicId, item.commentId, onSuccess)

                    }) {
                        Icon(painterResource(if (item.isLike) R.drawable.ic_thumb_up_24 else R.drawable.ic_thumb_up_off_alt_24), contentDescription = "赞")
                    }
                    // 赞数
                    Text(likeCount.intValue.toString())
                    // 踩
                    IconButton(onClick = {
                        val onSuccess = {
                            likeCount.value += if (item.isLike) -1 else 0
                            item.isDislike = !item.isDislike
                            item.isLike = false
                        }
                        if (item.commentId == 0) topicListViewModel.bad(topicId, onSuccess)
                        else commentListViewModel.bad(topicId, item.commentId, onSuccess)
                    }) {
                        Icon(painterResource(if (item.isDislike) R.drawable.ic_thumb_down_24 else R.drawable.ic_thumb_down_off_alt_24), contentDescription = "踩")
                    }

                }
            }
        }
    }
}

@Composable
fun SubCommentItem(
    item: CommentInfo,
    index: Int,
    userInfoState: State<UserInfo?>,
    onClickImage: (item: CommentInfo, url: String) -> Unit,
    onNavigateToUserCenter: (UserCenterRoute) -> Unit,
    onConfirmDeleteComment: (Int) -> Unit,
    onNavigateToReply: (Int) -> Unit = {},
    modifier: Modifier = Modifier,
    showButtons: Boolean = true
) {
    Card(
        modifier = modifier,
        border = BorderStroke(2.dp, CardDefaults.cardColors().disabledContentColor),
    ) {
        Column(modifier = Modifier.padding(4.dp)) {
            Row {
                Row(modifier = Modifier.clickable { onNavigateToUserCenter(UserCenterRoute(item.userId)) }) {
                    UserAvatar(item.userAvatar, Modifier
                        .clip(CircleShape)
                        .size(20.dp)
                    )
                    Text(item.userNickName)
                }

                if (item.replyTo != null) {
                    Row(modifier = Modifier.clickable { onNavigateToUserCenter(UserCenterRoute(item.replyToUid!!)) }) {
                        Text(" 回复: ")
                        Text(item.replyTo!!)
                    }
                }
            }
            // 正文
            HtmlText(item = item, html = item.content, onClickImage = onClickImage)
            // 发布时间
            Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
                Text(item.createTime, modifier = Modifier.graphicsLayer { alpha = 0.7f })
                if (showButtons) Row {
                    if (userInfoState.value?.uid == item.userId) IconButton(onClick = { onConfirmDeleteComment(item.commentId) }) {
                        Icon(Icons.Filled.Delete, contentDescription = "删除回复")
                    }
                    IconButton(onClick = {
                        onNavigateToReply(item.commentId)
                    }) {
                        Icon(painterResource(R.drawable.ic_comment_24), contentDescription = "回复它")
                    }
                }
            }
        }
    }
}



